package com.zyc.registry.zk;

import com.zyc.enums.RpcErrorMessageEnum;
import com.zyc.exception.RpcException;
import com.zyc.factory.SingletonFactory;
import com.zyc.loadbalance.LoadBalance;
import com.zyc.loadbalance.impl.ConsistentHashLoadBalance;
import com.zyc.registry.ServiceDiscovery;
import com.zyc.remoting.dto.RpcRequest;
import com.zyc.utils.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;

import java.net.InetSocketAddress;
import java.util.List;

/**
 * @author zyc
 * @create 2022--05--16 17:14
 */
@Slf4j
public class ZKServiceDiscoveryImpl implements ServiceDiscovery {
    private final LoadBalance loadBalance;

    public ZKServiceDiscoveryImpl() {
        //TODO 动态加载扩展程序
        this.loadBalance = SingletonFactory.getInstance(ConsistentHashLoadBalance.class);
    }

    @Override
    public InetSocketAddress lookupService(RpcRequest rpcRequest) throws RpcException {
        String rpcServiceName = rpcRequest.getRpcServiceName();
        CuratorFramework zkClient = CuratorUtils.getZkClient();
        List<String> serviceUrlList = CuratorUtils.getChildrenNodes(zkClient, rpcServiceName);
        if (CollectionUtil.isEmpty(serviceUrlList)) {
            throw new RpcException(RpcErrorMessageEnum.SERVICE_CAN_NOT_BE_FOUND, rpcServiceName);
        }
        String targetServiceUrl = loadBalance.selectServiceAddress(serviceUrlList, rpcRequest);
        log.info("成功找到服务地址:【{}】", targetServiceUrl);
        String[] socketAddressArray = targetServiceUrl.split(":");
        String host = socketAddressArray[0];
        int port = Integer.parseInt(socketAddressArray[1]);
        return new InetSocketAddress(host, port);
    }
}
